package calao.util.xml;

public class XmlElement <T extends Enum, A extends Enum>
{
	
	class Property
	{
		final A property;
		final String value;
		final Property next;
		Property(A attr, String value, Property next) {
			this.property = attr;
			this.value = value;
			this.next = next;
		}
	}
	
	final XmlParser<T,A> parser;
	final T tag;
	final XmlElement<T,A> parent;
	Object value;
	boolean empty = false;
	final int line, column;
	
	Property firstProperty;
		
	public XmlElement(T tag, XmlElement<T,A> parent, XmlParser<T,A> parser)
	{
		this.tag = tag;
		this.parent = parent;
		this.parser = parser;
		this.line = parser.line;
		this.column = parser.column;
	}

	public T getTag()
	{
		return tag;
	}
	
	public boolean getBoolean(A property)
	throws XmlParseException
	{
		return Boolean.parseBoolean(getNonNull(property));
	}
	
	public int getInt(A property)
	throws XmlParseException
	{
		return Integer.parseInt(getNonNull(property));
	}

	public long getLong(A property)
	throws XmlParseException
	{
		return Long.parseLong(getNonNull(property));
	}

	public String get(A property)
	{
		Property prop = firstProperty;
		while (prop!=null) {
			if (prop.property==property) return prop.value;
			prop = prop.next;
		}
		return null;
	}
	
	public String getNonNull(A property)
	throws XmlParseException
	{
		String value = get(property);
		if (value==null) parser.abortMissingProperty(property);
		return value;
	}

	public double getDouble(A property)
	throws XmlParseException
	{
		return Double.parseDouble(getNonNull(property));
	}
	
	public void setValue(Object value)
	{
		this.value = value;
	}
	
	public XmlElement getParent()
	{
		return parent;
	}
	
	public XmlElement getParent(T tag)
	{
		if (parent==null) return null;
		if (parent.tag==tag) return parent;
		return parent.getParent(tag);
	}

	public Object getParentValue(T tag)
	{
		if (parent==null) return null;
		if (parent.tag==tag) return parent.value;
		return parent.getParentValue(tag);
	}

	public Object getValue()
	{
		return value;
	}
	
	void addProperty(A prop, String value)
	{
		firstProperty = new Property(prop, value, firstProperty);
	}

}
